home *** CD-ROM | disk | FTP | other *** search
/ Computer Music Interactif…cial Edition 1999 Winter / cd 3.iso / mac / Mac / Shares / Midishare™1.68 / Development Tools / Sources Examples / SMPTEmonitor / smpteMonitor.c next >
Encoding:
C/C++ Source or Header  |  1994-03-22  |  15.8 KB  |  693 lines  |  [TEXT/MPS ]

  1. /********************************************************************************/
  2. /*                             SMPTE Monitor                                    */
  3. /*------------------------------------------------------------------------------*/
  4. /*                                                                                */
  5. /*------------------------------------------------------------------------------*/
  6. /*        © GRAME 1992, Yann Orlarey                                               */
  7. /********************************************************************************/
  8.  
  9. #include "MIDIShare.h"
  10.  
  11. #include <Values.h>
  12. #include <Types.h>
  13. #include <Resources.h>
  14. #include <QuickDraw.h>
  15. #include <Fonts.h>
  16. #include <Events.h>
  17. #include <Windows.h>
  18. #include <Menus.h>
  19. #include <TextEdit.h>
  20. #include <Dialogs.h>
  21. #include <Desk.h>
  22. #include <ToolUtils.h>
  23. #include <Memory.h>
  24. #include <SegLoad.h>
  25. #include <Files.h>
  26. #include <OSUtils.h>
  27. #include <OSEvents.h>
  28. #include <DiskInit.h>
  29. #include <Packages.h>
  30. #include <Traps.h>
  31.  
  32. /* Quelques constantes Macintosh */
  33.  
  34. #define nil                        0
  35. #define osEvent                 app4Evt
  36. #define    resumeMask                1
  37. #define    suspendResumeMessage    1
  38. #define mouseMovedMessage        0xFA
  39. #define _Unimplemented            0xA89F            /* Unimplemented trap                */
  40. #define _WaitNextEvent            0xA860            /* WaitNextEvent trap                */
  41.  
  42.  
  43. /* Une barre de menus minimale */
  44.  
  45. #define mBarSize    3
  46. #define    AppleMenu    0
  47. #define    FileMenu    1
  48. #define    EditMenu    2
  49.  
  50. #define    AppleID        128
  51. #define    FileID        129
  52. #define    EditID        130
  53.  
  54.  
  55. /* Les items du menu Edit    */
  56.  
  57. #define    UndoI        1
  58. #define    CutI        3
  59. #define    CopyI        4
  60. #define    PasteI        5
  61. #define    ClearI        6
  62.  
  63.  
  64. /* La fenêtre de l'application qui est en fait un dialog */
  65.  
  66. #define dialogID    129                         
  67.  
  68.  
  69. /* Pour les erreurs et le About    */
  70.  
  71. #define    AlertID        500
  72. #define    AboutID        128                    /* Dialog définit dans les ressources de MidiShareI    */
  73. #define    AboutPictID    130
  74.  
  75.  
  76. /* les contrôleurs du dialog */
  77.  
  78. #define MidiShareTime    18
  79. #define SmpteTime        19
  80. #define SyncLocked        20
  81.  
  82.  
  83. /* Variables globales d'une application Macintosh    */
  84.  
  85. WindowPtr    myWindow;                            /* fenêtre                            */
  86.  
  87. Boolean        doneFlag;                            /* flag d'arrêt                        */
  88.     
  89. SysEnvRec    gMac;                                /* machine…                            */
  90. Boolean        hasWNE;                                /* vrai si WaitNextEvent implémenté    */
  91. Boolean        foreGround;                            /* vrai si en foreGround            */
  92.  
  93. EventRecord    myEvent;                            /* pour la main event loop            */
  94. char        theChar;                            /* pour la gestion des touches        */
  95. Rect        dragRect;                            /* rect de déplacement de fenêtre    */
  96. MenuHandle    myMenus[mBarSize];                    /* les menus                        */
  97.  
  98.  
  99. /* Constantes pour paramétrer l'application    */
  100.  
  101. #define ApplName         "\pSmpte Monitor"
  102.  
  103.  
  104. /* Variables globales pour MidiShare    */
  105.  
  106. short        myRefNum;                            /* numéro d'appl. Midi                */
  107. TSyncInfo    gInfo;
  108.  
  109. ControlHandle    msTimeHandler;
  110. ControlHandle    smpteTimeHandler;
  111. ControlHandle    syncLockedHandler;
  112.  
  113.  
  114. pascal void DisplayState( long , short , long, long, long);
  115. void DrawSmpteInfo(WindowPtr wind);
  116.  
  117.  
  118. /********************************************************************************/
  119. /*                             Standard Macintosh Routines                          */
  120. /*                                                                                 */
  121. /********************************************************************************/
  122.  
  123.  
  124. /*================================== Utilities =================================*/
  125.  
  126.  
  127. void AlertUser( char *msg )                    
  128. {
  129.     ParamText( ApplName, msg, "\p", "\p");
  130.     Alert(AlertID,nil);
  131.     ExitToShell();                                
  132. }
  133.  
  134.  
  135. Boolean        TrapAvailable(short    trapNum, short tType)
  136. {
  137.     if ( (tType == ToolTrap)  &&                        /* Toolbox trap        */
  138.          (gMac.machineType > envMachUnknown)  &&        /* …512KE, Plus, or    */
  139.          (gMac.machineType < envMacII) ) {                /* …SE                */
  140.          
  141.         trapNum &= 0x3FF;                /* Traps numbers are 10 bits long    */
  142.         
  143.         if (trapNum > 0x1FF) {            /* Traps only go up to 0x1FF on        */
  144.             return(false);                /*   these machines                    */
  145.         }
  146.     }
  147.     return NGetTrapAddress(trapNum, tType) != GetTrapAddress(_Unimplemented);
  148. }
  149.  
  150.  
  151. Boolean IsAppWindow (WindowPtr wind)
  152. {
  153.     return  wind ? ((WindowPeek)wind)->windowKind >= 0 : false ;
  154. }
  155.  
  156.  
  157. Boolean IsDAWindow (WindowPtr wind)
  158. {
  159.     return  wind ? ((WindowPeek)wind)->windowKind < 0 : false ;
  160. }
  161.  
  162.  
  163. void CloseWind (WindowPtr wind)
  164. {
  165.     if ( IsDAWindow(wind) )
  166.         CloseDeskAcc( ((WindowPeek)wind)->windowKind );
  167.     else if ( IsAppWindow(wind) )
  168.         DisposeWindow(wind);
  169. }
  170.  
  171. void CloseAllWinds (WindowPtr wind)
  172. {
  173.     if (wind) {
  174.         CloseAllWinds( (WindowPtr) (((WindowPeek)wind)->nextWindow) );
  175.         CloseWind(wind);
  176.     }
  177. }
  178.  
  179.  
  180.  
  181. /*================================== pascal strings =================================*/
  182.  
  183.  
  184. void InsertCh( Str255 s, short p, char c)        /* Insert un caractère dans une chaine Pascal    */
  185. {                                                /* à partir de la position p (de 1 à n).        */
  186.     register short n;        
  187.     register char t;
  188.         
  189.     if (p >= s[0])
  190.         s[s[0]] = c;
  191.     else
  192.         for (n= s[0]-p; n>=0; n--, p++) { t=c; c=s[p]; s[p]=t; }
  193.     s[0]++;
  194. }
  195.  
  196. void ShiftPStr( Str255 s, short n )                /* Décale une chaine Pascal de n caractères      */
  197. {                                                /* vers la droite.                                 */
  198.     register char *ps;
  199.     register char *pd;
  200.     
  201.     ps = (char*)s + s[0];
  202.     pd = ps + n;
  203.     s[0] += n;
  204.     for (; n>0; n--) *pd-- = *ps-- ;
  205. }
  206.  
  207. void TransfPStr(Str255 s1, char* s2, short n)    /* Ecrase le début de la chaine s1 avec s2         */
  208. {
  209.     for (; n>0; n--) *++s1 = *++s2 ;
  210. }
  211.  
  212. void AddFirst( Str255 s1, char * s2)            /* Insere en début de la chaine s1 la chaine s2    */
  213. {
  214.     ShiftPStr( s1, s2[0] );
  215.     TransfPStr( s1, s2, s2[0] );
  216. }
  217.  
  218.  
  219.  
  220. /*================================== Dialog Items =================================*/
  221.  
  222.  
  223. void WindSetItemText (WindowPtr wind, short theItem, Str255 str)
  224. {
  225.     Rect    theRect;
  226.     short    theType;
  227.     Handle    theItemH;
  228.     
  229.     GetDItem((DialogPtr)wind, theItem, &theType, &theItemH, &theRect);
  230.     SetIText(theItemH, str);
  231. }
  232.     
  233. void WindHiliteItem (WindowPtr wind, short theItem, short value)
  234. {
  235.     Rect    theRect;
  236.     short    theType;
  237.     Handle    theItemH;
  238.     
  239.     GetDItem((DialogPtr)wind, theItem, &theType, &theItemH, &theRect);
  240.     HiliteControl((ControlHandle)theItemH, value);
  241. }
  242.     
  243. void WindGetItemText (WindowPtr wind, short theItem, Str255 str)
  244. {
  245.     Rect    theRect;
  246.     short    theType;
  247.     Handle    theItemH;
  248.     
  249.     GetDItem((DialogPtr)wind, theItem, &theType, &theItemH, &theRect);
  250.     GetIText(theItemH, str);
  251. }
  252.     
  253. void WindSetItemNum (WindowPtr wind, short theItem, long num)
  254. {
  255.     Str255    str;
  256.     
  257.     NumToString(num, str);
  258.     WindSetItemText(wind, theItem, str);
  259. }
  260.  
  261. void WindGetItemNum (WindowPtr wind, short theItem, long* num)
  262. {
  263.     Str255    str;
  264.     
  265.     WindGetItemText(wind, theItem, str);
  266.     StringToNum(str, num);
  267. }
  268.  
  269. void TrackDialog(WindowPtr w, Point p)
  270. {
  271.     short itemHit= 0;
  272.     
  273.     SetPort(w);
  274.     GlobalToLocal(&p);                                /* conversion du point en local    */
  275.     if( DialogSelect( &myEvent, &w, &itemHit))
  276.     {
  277.         switch( itemHit)
  278.         {
  279.             case MidiShareTime:
  280.                 MidiSetSyncMode(0);
  281.                 DisplayState( nil, nil, nil, nil, nil);
  282.                 break;
  283.             case SmpteTime:
  284.                 MidiSetSyncMode(MIDISyncExternal | MIDISyncAnyPort);
  285.                 DisplayState( nil, nil, nil, nil, nil);
  286.                 break;
  287.         }
  288.     }
  289. }
  290.  
  291.  
  292.  
  293. /*================================== About Dialog =================================*/
  294.  
  295.  
  296. //_______________________________________________________________________________________
  297. void UpdateWindow( WindowPtr w)
  298. {
  299.     if( IsAppWindow( w))
  300.     {
  301.         BeginUpdate( w);
  302.         if ( !EmptyRgn( w->visRgn ))
  303.         {
  304.             SetPort( w);
  305.             DrawDialog( w);
  306.         }
  307.         EndUpdate( w);
  308.     }
  309. }
  310.  
  311. void ShowAbout()
  312. {                                            
  313.     DialogPtr    myDialog;                    
  314.     Boolean     done= false;
  315.  
  316.     myDialog = GetNewDialog(AboutID,nil,(WindowPtr) -1);
  317.     if (myDialog) {
  318.         ShowWindow( (WindowPtr)myWindow);
  319.         while (!done) {
  320.             if (hasWNE) 
  321.                 WaitNextEvent(everyEvent, &myEvent, 0, nil);
  322.             else {
  323.                 SystemTask();
  324.                  GetNextEvent(everyEvent, &myEvent);
  325.             }
  326.             switch( myEvent.what ) {
  327.                 case mouseDown:
  328.                     done= true;
  329.                     break;
  330.                 case osEvent:
  331.                     if( (myEvent.message >> 24) == suspendResumeMessage)
  332.                         if( !(foreGround = myEvent.message & resumeMask))
  333.                             done= true;
  334.                     break;
  335.                 case updateEvt:
  336.                     UpdateWindow( (WindowPtr)myEvent.message);
  337.                     break;
  338.             }
  339.         }
  340.         DisposDialog( myDialog);
  341.     }
  342.     else SysBeep(0);
  343. }
  344.  
  345.  
  346.  
  347. /*================================== Mac events =================================*/
  348.  
  349.  
  350. void AdjustMenus() 
  351. {
  352.     if ( IsAppWindow( FrontWindow() ) ) 
  353.     {
  354.         DisableItem( myMenus[EditMenu], UndoI );
  355.         DisableItem( myMenus[EditMenu], CutI );
  356.         DisableItem( myMenus[EditMenu], CopyI );
  357.         DisableItem( myMenus[EditMenu], PasteI );
  358.         DisableItem( myMenus[EditMenu], ClearI );
  359.     } 
  360.     else if ( IsDAWindow( FrontWindow() ) ) 
  361.     {
  362.         EnableItem( myMenus[EditMenu], UndoI );
  363.         EnableItem( myMenus[EditMenu], CutI );
  364.         EnableItem( myMenus[EditMenu], CopyI );
  365.         EnableItem( myMenus[EditMenu], PasteI );
  366.         EnableItem( myMenus[EditMenu], ClearI );
  367.     }
  368. }            
  369.  
  370.  
  371. void AdjustCursor() 
  372. {
  373.     if (foreGround && IsAppWindow(FrontWindow())) 
  374.         SetCursor(&qd.arrow);
  375. }
  376.  
  377.  
  378. void DoCommand(long mResult)
  379. {
  380.     short    theItem;
  381.     short    theMenu;
  382.     Str255    name;
  383.  
  384.     theItem = LoWord(mResult);
  385.     theMenu = HiWord(mResult);
  386.     
  387.     switch ( theMenu )
  388.     {
  389.         case AppleID:
  390.             if (theItem != 1) 
  391.             {
  392.                 GetItem(myMenus[AppleMenu], theItem, name);
  393.                 theItem = OpenDeskAcc(name);
  394.             } else {
  395.                 ShowAbout();
  396.             }
  397.             break;
  398.         case EditID:
  399.             SystemEdit( theItem-1 );
  400.             break;
  401.         case FileID: 
  402.             doneFlag = true;
  403.             break;
  404.     }
  405.     HiliteMenu(0);  
  406. }
  407.  
  408.  
  409. void DoMouseDown() 
  410. {
  411.     WindowPtr whichWindow;
  412.     
  413.     switch ( FindWindow( myEvent.where, &whichWindow ) )
  414.     { 
  415.         case inMenuBar:    
  416.                 AdjustMenus(); 
  417.                 DoCommand(MenuSelect(myEvent.where));
  418.                 break;
  419.         case inSysWindow: 
  420.                 SystemClick(&myEvent, whichWindow);
  421.                 break;
  422.         case inGoAway:      
  423.                 doneFlag = TrackGoAway(whichWindow, myEvent.where);
  424.                 break;
  425.         case inDrag:      
  426.                 DragWindow(whichWindow, myEvent.where, &dragRect);
  427.                 break;
  428.         case inContent:      
  429.                 if (whichWindow != FrontWindow())
  430.                     SelectWindow(whichWindow);
  431.                 else if (whichWindow == myWindow)
  432.                     TrackDialog(myWindow, myEvent.where);
  433.                 break;
  434.     }
  435. }
  436.  
  437.  
  438.  
  439. /*================================== Initialize =================================*/
  440.  
  441. pascal void displayLock( long , short , long, long, long)
  442. {
  443.     if( gInfo.syncLocked)    SetIText( (Handle)syncLockedHandler, "\pSync. locked");
  444.     else                    SetIText( (Handle)syncLockedHandler, "\p");
  445. }
  446.  
  447. pascal void displayTime( long , short , long, long, long)
  448. {
  449.     short midi= 1, smpte= 0;
  450.     
  451.     if( gInfo.syncMode & MIDISyncExternal)
  452.     {
  453.         midi = 0;
  454.         smpte= 1;
  455.     }
  456.     SetCtlValue( msTimeHandler, midi);
  457.     SetCtlValue( smpteTimeHandler, smpte);
  458. }
  459.  
  460. pascal void DisplayState( long , short , long, long, long)
  461. {
  462.     MidiGetSyncInfo(&gInfo);
  463.     displayLock( nil, nil, nil, nil, nil);
  464.     displayTime( nil, nil, nil, nil, nil);
  465. }
  466.  
  467.  
  468. void SetUpWindows()
  469. {
  470.     short type;
  471.     Rect box;
  472.  
  473.     SetRect (&dragRect, qd.screenBits.bounds.left, qd.screenBits.bounds.top, 
  474.                         qd.screenBits.bounds.right,qd.screenBits.bounds.bottom);
  475.     InsetRect (&dragRect, 4, 4);
  476.  
  477.      myWindow = GetNewDialog (dialogID, nil, (WindowPtr) -1);
  478.     if( myWindow)
  479.     {
  480.         GetDItem( myWindow, MidiShareTime, &type, (Handle *)&msTimeHandler, &box);
  481.         GetDItem( myWindow, SmpteTime, &type, (Handle *)&smpteTimeHandler, &box);
  482.         GetDItem( myWindow, SyncLocked, &type, (Handle *)&syncLockedHandler, &box);
  483.         SetPort(myWindow);
  484.         TextFont(systemFont); TextSize(12); TextMode(srcCopy); PenNormal();
  485.         ShowWindow(myWindow);
  486.         DisplayState( nil, nil, nil, nil, nil);
  487.     }
  488.     else AlertUser( "\pcan't find DLOG resource !");
  489. }
  490.  
  491.  
  492. void SetUpMenus()
  493. {
  494.     short    i;
  495.         
  496.     myMenus[AppleMenu] = GetMenu(AppleID);
  497.     AddResMenu(myMenus[AppleMenu],'DRVR');
  498.     myMenus[FileMenu] = GetMenu(FileID);
  499.     myMenus[EditMenu] = GetMenu(EditID);
  500.     for (i = AppleMenu; i <= EditMenu; i++)
  501.         InsertMenu(myMenus[i], 0);
  502.     DrawMenuBar();
  503. }            
  504.  
  505.  
  506. void Initialize()
  507. {
  508.     OSErr    err;
  509.  
  510.     err = SysEnvirons(1, &gMac);
  511.     if (gMac.machineType < 0) AlertUser( "\pneed at least 128K ROMs" );
  512.     hasWNE = TrapAvailable(_WaitNextEvent, ToolTrap);
  513.     foreGround = true;
  514.         
  515.     InitGraf(&qd.thePort);                                
  516.     InitFonts();                                       
  517.     InitWindows();                                       
  518.     InitDialogs(nil);                                   
  519.     InitMenus();                                       
  520.     TEInit();                                           
  521.     InitCursor();                                        
  522.  
  523.     FlushEvents(everyEvent, 0);                        
  524.  
  525.     SetUpMenus();                                    
  526.     SetUpWindows();                                    
  527. }
  528.  
  529.  
  530.  
  531. /********************************************************************************/
  532. /*                                 Do Idle                                            */
  533. /********************************************************************************/
  534. void DoIdle()
  535. {
  536.     register long    n;
  537.     register short     r;
  538.     
  539.     DrawSmpteInfo( myWindow);
  540.     r = myRefNum;
  541.     for (n=MidiCountDTasks(r); n>0; --n) MidiExec1DTask(r);
  542. }
  543.  
  544.  
  545. /********************************************************************************/
  546. /*                                 MidiShare specific                                */
  547. /*                                                                                 */
  548. /********************************************************************************/
  549.  
  550.  
  551. /*=================================== alarms ===================================*/
  552.  
  553.  
  554. pascal void ApplAlarm( short r, long code)
  555. {
  556.     MidiGetSyncInfo(&gInfo);
  557.     if( code == MIDISyncStart)
  558.         MidiDTask( displayLock, MidiGetTime(), r, 0L,0L,0L);
  559.     else if( code == MIDISyncStop )
  560.         MidiDTask( displayLock, MidiGetTime(), r, 0L,0L,0L);
  561.     else if( code == MIDIChangeSync)
  562.         MidiDTask( DisplayState, MidiGetTime(), r, 0L,0L,0L);
  563. }
  564.  
  565.  
  566. pascal void IgnoreEvents (register short r)
  567. {
  568.     // our receive alarm ignore all incoming events
  569.     
  570.     MidiFlushEvs(r);
  571. }
  572.  
  573.  
  574. /*=================================== Initialize ===================================*/
  575.  
  576.  
  577. void SetUpMidi()
  578. {
  579.     // first check for MidiShare installed
  580.     if (!MidiShare()) { AlertUser( "\pMidiShare not implemented" ); }
  581.     
  582.     // then start the MidiShare session and check for no errors
  583.     myRefNum= MidiOpen(ApplName);                            
  584.     if (myRefNum < 0) { AlertUser( "\pError opening the MidiShare session"); } 
  585.     
  586.     // install our alarms 
  587.     MidiSetRcvAlarm(myRefNum, IgnoreEvents);
  588.     MidiSetApplAlarm(myRefNum, ApplAlarm);
  589.     
  590.     // get the current synchronisation informations
  591.     MidiGetSyncInfo(&gInfo);
  592. }
  593.  
  594.  
  595. /*=================================== smpte monitor ===================================*/
  596.  
  597.  
  598. long oldpo = -2;
  599. long oldbr = -1;
  600. long oldfo = -1;
  601. long oldsub = 0;
  602. long oldfr = 0;
  603. long oldss = 0;
  604. long oldmn = 0;
  605. long oldhh = 0;
  606. char*    formatNames[] = {"\p24", "\p25", "\p30df", "\p30"}; 
  607.  
  608. void DrawSmpteInfo(WindowPtr wind)
  609. {
  610.     TSmpteLocation loc;
  611.  
  612.     if (gInfo.syncBreaks != oldbr) {oldbr = gInfo.syncBreaks; WindSetItemNum(wind, 8, gInfo.syncBreaks);}
  613.     if (gInfo.syncLocked) {
  614.         if (gInfo.syncPort != oldpo) {oldpo = gInfo.syncPort; WindSetItemNum(wind, 7, gInfo.syncPort);}
  615.  
  616.         MidiTime2Smpte(MidiGetExtTime(), gInfo.syncFormat, &loc);
  617.     
  618.         if (loc.hours != oldhh) {oldhh = loc.hours; WindSetItemNum(wind, 1, loc.hours);}
  619.         if (loc.minutes != oldmn) {oldmn = loc.minutes; WindSetItemNum(wind, 2, loc.minutes);}
  620.         if (loc.seconds != oldss) {oldss = loc.seconds; WindSetItemNum(wind, 3, loc.seconds);}
  621.         if (loc.frames != oldfr) {oldfr = loc.frames; WindSetItemNum(wind, 4, loc.frames);}
  622.         if (loc.fracs != oldsub) {oldsub = loc.fracs; WindSetItemNum(wind, 5, loc.fracs);}
  623.         if (loc.format != oldfo) {oldfo = loc.format; WindSetItemText(wind, 6, formatNames[loc.format]);}
  624.     }
  625.     else if (-1 != oldpo){oldpo = -1; WindSetItemText(wind, 7, "\p--");}
  626. }
  627.  
  628. /********************************************************************************/
  629. /*                                         Main                                    */
  630. /*                                                                                 */
  631. /********************************************************************************/
  632.  
  633. void main()
  634. {
  635.     Boolean b;
  636.     
  637.     MaxApplZone();
  638.     Initialize();
  639.     SetUpMidi();                                    
  640.     
  641.     doneFlag = false;                                            
  642.     while (!doneFlag) {                                            /* Main Loop                */
  643.         if (hasWNE) 
  644.             b = WaitNextEvent(everyEvent, &myEvent, 0, nil);    /* no sleep, no mouseRgn    */
  645.         else {
  646.             SystemTask();
  647.              b = GetNextEvent(everyEvent, &myEvent);
  648.         }
  649.         AdjustCursor();    
  650.                                                 
  651.         switch( myEvent.what ) {
  652.             case nullEvent:
  653.                     DoIdle();
  654.                     break;
  655.             case osEvent:
  656.                     switch (myEvent.message >> 24) {
  657.                         case suspendResumeMessage:
  658.                             foreGround = myEvent.message & resumeMask;
  659.                             break;
  660.                         case mouseMovedMessage:
  661.                             DoIdle();
  662.                             break;
  663.                     }
  664.                     break;
  665.             case keyDown:
  666.             case autoKey:
  667.                     theChar = myEvent.message & charCodeMask;
  668.                     if (myEvent.modifiers & cmdKey ) {
  669.                         AdjustMenus();
  670.                         DoCommand(MenuKey(theChar));
  671.                     }
  672.                     break;
  673.             case mouseDown:
  674.                     DoMouseDown();
  675.                     break;
  676.             case updateEvt:
  677.                     if ( IsAppWindow( (WindowPtr)myEvent.message ) )
  678.                         UpdateWindow( (WindowPtr)myEvent.message);
  679.                     break;
  680.         }
  681.     }
  682.     MidiClose(myRefNum);                        
  683.     CloseAllWinds( FrontWindow() );
  684. }
  685.  
  686.  
  687.  
  688.  
  689.  
  690.  
  691.     
  692.  
  693.